package com.link.play.fit.ai.ui.adjust

import android.annotation.SuppressLint
import android.os.Bundle
import android.text.Editable
import android.text.InputFilter
import android.text.TextWatcher
import android.view.View
import android.view.ViewGroup
import androidx.activity.addCallback
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.link.play.fit.ai.GlobalConfig
import com.link.play.fit.ai.R
import com.link.play.fit.ai.base.BaseActivity
import com.link.play.fit.ai.base.goToAc
import com.link.play.fit.ai.bean.BaseEventData
import com.link.play.fit.ai.bean.CalendarStatusData
import com.link.play.fit.ai.bean.LogWeightBean
import com.link.play.fit.ai.bean.UserGuide
import com.link.play.fit.ai.databinding.AdjustGoalsActivityBinding
import com.link.play.fit.ai.ext.d
import com.link.play.fit.ai.store.CloudStore
import com.link.play.fit.ai.store.CloudStore.DOC_CALENDAR_STATUS_LIST_DATA_KEY
import com.link.play.fit.ai.store.CloudStore.DOC_LOG_WEIGHT
import com.link.play.fit.ai.ui.adjust.adjustPage.AdjustPageActivity
import com.link.play.fit.ai.utils.DateEx.getDayOfMonth
import com.link.play.fit.ai.utils.DateEx.getTimeStamp
import com.link.play.fit.ai.utils.ScreenUtil.Companion.dpToPx

import com.link.play.fit.ai.utils.getCarbsByCal
import com.link.play.fit.ai.utils.getFatsByCal
import com.link.play.fit.ai.utils.getProteinByCal
import com.link.play.fit.ai.utils.kgCal
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.math.roundToInt

class AdjustGoalsActivity :
    BaseActivity<AdjustGoalsActivityBinding>(AdjustGoalsActivityBinding::inflate) {
    private var userGuide: UserGuide? = null

    private var calendarStatusData: CalendarStatusData? = null
    private companion object {
        val DIGIT_REGEX = "\\d*".toRegex()
        val VALID_INPUT_REGEX = "0|[1-9]\\d*".toRegex()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        calendarStatusData = intent.getSerializableExtra("data") as CalendarStatusData?
        "userGuide  $calendarStatusData".d()
        initView()
        initListener()
        EventBus.getDefault().register(this)

    }

    @SuppressLint("SetTextI18n", "UseCompatLoadingForDrawables")
    private fun initView() {
        setData()
        setupEditTexts()

    }

    private fun initListener() {
        onBackPressedDispatcher.addCallback {

            finishAfterTransition()
        }
        binding.backImage.setOnClickListener { onBackPressedDispatcher.onBackPressed() }
        binding.autoText.setOnClickListener { saveAllGoalsAndNavigate() }
        binding.doneText.setOnClickListener { saveGoalsAndFinish() }
        binding.revertText.setOnClickListener { setData()
            binding.buttonLayout.isVisible=false}
    }

    @SuppressLint("SetTextI18n")
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: BaseEventData) {
        when (event.type) {
            "byAdjustPage" -> {
                customDailyPlan(event.recentlyGoalData)
            }
        }

    }

    // region EditText 相关逻辑
    private fun setupEditTexts() {
        // 统一配置所有输入框
        val editTexts = listOf(
            binding.calorieEdit,
            binding.proteinEdit,
//            binding.carbedit,
            binding.fatEdit
        )

        // 设置输入过滤器
        editTexts.forEach { it.filters = arrayOf(createInputFilter()) }

        // 设置文本监听
        val textWatcher = createTextWatcher()
        editTexts.forEach { it.addTextChangedListener(textWatcher) }
        binding.carbedit.addTextChangedListener(textWatcher)
    }

    private fun createInputFilter() = InputFilter { source, start, end, dest, dstart, dend ->
        val newText = buildString {
            append(dest.subSequence(0, dstart))
            append(source.subSequence(start, end))
            append(dest.subSequence(dend, dest.length))
        }

        when {
            !newText.matches(DIGIT_REGEX) -> ""
            newText.length > 1 && newText.startsWith("0") -> ""
            newText.length > 5 -> ""
            else -> null
        }
    }

    private fun createTextWatcher() = object : TextWatcher {
        override fun afterTextChanged(s: Editable) {
            binding.buttonLayout.visibility = if (validateInput(s)) View.VISIBLE else View.GONE
        }

        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
    }

    // region 焦点监听
    @SuppressLint("UseCompatLoadingForDrawables")
    private fun setupFocusListeners() {
        val focusPairs = listOf(
            binding.calorieEdit to binding.calorieFrLayout,
            binding.proteinEdit to binding.proteinFr,
            binding.carbedit to binding.carbeditFr,
            binding.fatEdit to binding.fatFr
        )

        focusPairs.forEach { (editText, frameLayout) ->
            editText.setOnFocusChangeListener { _, hasFocus ->
                frameLayout.background = getDrawable(
                    if (hasFocus) R.drawable.bg_a_style_04_black
                    else R.drawable.bg_a_style_04
                )
            }
        }
    }

    @SuppressLint("SetTextI18n")
    private fun setData() {
        lifecycleScope.launch {
            userGuide = CloudStore.get<UserGuide>(CloudStore.DOC_USER_GUIDE)
            "userGuide $userGuide".d()
        }
        with(binding) {
            calendarStatusData?.let {
                calorieEdit.setText(it.caloriesDaily.toString())
                proteinEdit.setText(it.proteinDaily.toString())
                carbedit.setText(it.carbsDaily.toString())
                fatEdit.setText(it.fatsDaily.toString())

                caloriesBar.max = it.caloriesDaily
                caloriesBar.progress = it.consumeCaloriesDaily

                proteinProgress.max = it.proteinDaily
                proteinProgress.progress = it.consumeProteinDaily

                carbProgress.max = it.carbsDaily
                carbProgress.progress = it.consumeCarbsDaily

                fatProgress.max = it.fatsDaily
                fatProgress.progress = it.consumeFatsDaily
            }

        }
        setupFocusListeners()
    }

    private fun saveAllGoalsAndNavigate() {
        goToAc(AdjustPageActivity::class.java) {
            userGuide?.let {
                putExtra("bean", it)
            }
        }
    }

    private fun saveGoalsAndFinish() {
        with(binding) {
            userGuide?.let { k ->
                calorieEdit.text.takeIf { it.isNotEmpty() }?.let {
                    k.caloriesDaily = it.toString().toInt()
                }
                proteinEdit.text.takeIf { it.isNotEmpty() }?.let {
                    k.proteinDaily = it.toString().toInt()

                }
                carbedit.text.takeIf { it.isNotEmpty() }?.let {
                    k.carbsDaily = it.toString().toInt()
                }
                fatEdit.text.takeIf { it.isNotEmpty() }?.let {
                    k.fatsDaily = it.toString().toInt()
                }
                CloudStore.set(CloudStore.DOC_USER_GUIDE, k)
            }
            calendarStatusData?.let { k ->
                calorieEdit.text.takeIf { it.isNotEmpty() }?.let {
                    k.caloriesDaily = it.toString().toInt()
                }
                proteinEdit.text.takeIf { it.isNotEmpty() }?.let {
                    k.proteinDaily = it.toString().toInt()

                }
                carbedit.text.takeIf { it.isNotEmpty() }?.let {
                    k.carbsDaily = it.toString().toInt()
                }
                fatEdit.text.takeIf { it.isNotEmpty() }?.let {
                    k.fatsDaily = it.toString().toInt()
                }
                updateCalendarListData(k)
            }
        }
        EventBus.getDefault().post(calendarStatusData)
        onBackPressedDispatcher.onBackPressed()

    }

    private fun validateInput(input: CharSequence) =
        input.isNotBlank() && input.matches(VALID_INPUT_REGEX)

//    private fun changeWindow() {
//        window.decorView.setOnApplyWindowInsetsListener { view, insets ->
//            (binding.buttonLayout.layoutParams as? ViewGroup.MarginLayoutParams)?.apply {
//                bottomMargin = insets.systemWindowInsetBottom - dpToPx(40F).toInt()
//                binding.buttonLayout.layoutParams = this
//            }
//            insets
//        }
//    }

    /**
     * 计算每日目标值
     */
    @SuppressLint("SetTextI18n")
    fun customDailyPlan(recentlyGoalData: UserGuide) {

        var caloriesDaily = 0
        var proteinDaily = 0
        var fatsDaily = 0
        var carbsDaily = 0
        val dailyCal = recentlyGoalData.perWeightKg / 7f * kgCal
        "dailyCal  $dailyCal".d()
        val action = {
            val d = if (recentlyGoalData.gender == 0) 1.0f else 0.75f
            proteinDaily =
                getProteinByCal(recentlyGoalData.goalWeightLbs, recentlyGoalData.caloriesDaily, d)
            fatsDaily = getFatsByCal(caloriesDaily)
            carbsDaily = getCarbsByCal(caloriesDaily, proteinDaily, fatsDaily)
        }
        when (recentlyGoalData.goal) {
            0 -> {
                caloriesDaily = recentlyGoalData.bmr + dailyCal.roundToInt()
                action.invoke()
            }

            1 -> {
                caloriesDaily = recentlyGoalData.bmr
                action.invoke()
            }

            2 -> {
                caloriesDaily = recentlyGoalData.bmr - dailyCal.roundToInt()
                action.invoke()
            }
        }

        userGuide = recentlyGoalData.copy()
        userGuide?.let {
            it.caloriesDaily = caloriesDaily
            it.proteinDaily = proteinDaily
            it.fatsDaily = fatsDaily
            it.carbsDaily = carbsDaily
            CloudStore.set(CloudStore.DOC_USER_GUIDE, it)
            GlobalConfig.imperialMetric = it.imperialMetric
            CloudStore.addToList(
                DOC_LOG_WEIGHT,
                DOC_LOG_WEIGHT,
                getDayOfMonth(),
                LogWeightBean(it.weightKg, it.weightLbs)
            )
        }
        calendarStatusData?.let {
            it.caloriesDaily = caloriesDaily
            it.proteinDaily = proteinDaily
            it.fatsDaily = fatsDaily
            it.carbsDaily = carbsDaily
            setData()
            updateCalendarListData(it)
            EventBus.getDefault().post(it)
        }
        "userGuide  $userGuide".d()

//        EventBus.getDefault()
//            .post(BaseEventData(type = "byAdjustGoals", recentlyGoalData = userGuide!!))

    }

    private fun updateCalendarListData(oldData: CalendarStatusData) {
        CloudStore.addToList(
            CloudStore.DOC_CALENDAR_STATUS_LIST_DATA,
            date = DOC_CALENDAR_STATUS_LIST_DATA_KEY,
            key = getTimeStamp(oldData.timeDate),
            data = oldData
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)

    }
}